/** @jsxImportSource @emotion/react */
import {jsx, SerializedStyles} from "@emotion/react";
import * as React from "react";
import PropTypes from "prop-types";
// import { Text } from "./Text";
// import { MenuLabel } from "./Menu";
// import { useTheme } from "./Theme/Providers";
// import { noOp } from "./misc/noop";
// import { OnPressFunction, useTouchable } from "./Hooks/touchable-hook";
// import { safeBind } from "./Hooks/compose-bind";

import {
    useTheme,
    VisuallyHidden,
    IconAlertCircle, IconChevronDown,
    getHeight, focusShadow, ButtonSize,
    Text, LabelText,
    Theme,  MenuLabel
} from "customize-easy-ui-component";
import {noOp} from "customize-easy-ui-component/esm/misc/noop";
import {safeBind} from "customize-easy-ui-component/esm/Hooks/compose-bind";
import {OnPressFunction, useTouchable} from "../../../../customize-easy-ui-component/src/Hooks/pressable-hook";




export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
  /** A series of ListItem elements */
  children?: React.ReactNode;
}

export const List: React.FunctionComponent<ListProps> = ({
  children,
  ...other
}) => {
  return <nav {...other}>{children}</nav>;
};

List.propTypes = {
  children: PropTypes.node
};

interface ListItemProps extends React.HTMLAttributes<any> {
  onPress?: OnPressFunction;
  /**主体标签 =div */
  component?: React.ElementType<any>;

  /** An icon or avatar to appear to the left of the text content
   * 应该安排视觉宽度很小的内容。 会在垂直高度方向上居中显示；
   *  */
  contentBefore?: React.ReactNode;
  /** an icon to appear to the right of the text content
   * 应该安排视觉宽度很小的内容。 会在垂直高度方向上居中显示；
   * */
  contentAfter?: React.ReactNode;

  /** whether the list item is interactive (ie., can be clicked as a button) */
  interactive?: boolean;
  /** optional third row of content
   * 更多内容： 可选的  扩展第三行的。
   * */
  children?: React.ReactNode;
  /** whether primary and secondary text should be wrapped */
  wrap?: boolean;
  /** The primary text content of the list item
   * 第一行 主要内容
   * */
  primary: string | React.ReactNode;
  /** the secondary text content
   * 第二行 可选的 内容。
   * */
  secondary?: string | React.ReactNode;
  noBind?:boolean;  //防止Can't perform a React state update on an unmounted component
  terminateOnScroll?: boolean;
  delay?: number;
  //对第二行secondary整行的控制
  secondStyle?: SerializedStyles;
  [key: string]: any; // back hack to permit things like to='/page'
}
/**准备替换掉旧的 ListItem, #简易版本。没有用旧的"react-gesture-responder"包！
 * [考虑] 没必要提供拉拽的同时取消当前点击到的ListItem避免触发。 而触摸屏本就没这样问题。
 * 列表底下的各个项目：可以插入大类分类层次 ListSection。
 *    <ListSection >
         <ListItem  />
      </ListSection>
      <Divider muted />
  若通过<ListItemcss={{padding: "0.3rem 0.3rem",}}的，在这里实际由...other接受了外部样式注入修改。
   [准备移除 ] useTouchable ？
 #问题：轮播台电脑模式拉动触发，同时触发点击。旧版本:会存在等待进一步Move消息可能会取消的步骤。
 ？也许考虑：增加一种特别ListItem组件PanListItem可以允许电脑鼠标模式可以拉动任何区域而不会触发onClick事件的。
 * */
export const List2Item: React.FunctionComponent<ListItemProps> = ({
  primary,
  secondary,
  contentBefore,
  interactive = true,
  children,
  wrap = true,
  contentAfter,
  onPress = noOp,
  component: Component = "div",
  noBind=false,
  terminateOnScroll = false,
  delay=30,
  secondStyle,
  ...other
}) => {
  const interactiveProps = interactive
    ? {
        role: "button",
        tabIndex: 0
      }
    : {};
  const isLink = other.to || other.href;
  //这个{bind｛ref｝}给了哪一个Div;那么就针对哪一个DIV的矩形框框才能触发函数 onPress()。从z-index维度上看上一层的更小的div优先。
  const { bind, hover, active } = useTouchable({
    onPress,
    behavior: isLink ? "link" : "button"
  });
  const theme = useTheme();
  //console.log("ListItemdl=",delay, "terminateOnScroll=",terminateOnScroll);

  return (
    <Component
      className="ListItem"
      css={[
        {
          display: "block",
          textDecoration: "none",
          outline: "none",
          padding: theme.spaces.sm,
          background: "transparent",
          WebkitTapHighlightColor: "transparent",
          transition: "background 0.07s ease",
          [theme.mediaQueries.lg]: {
            paddingLeft: theme.spaces.lg,
            paddingRight: theme.spaces.lg
          },
          ":last-child": {
            borderBottom: "none"
          }
        },

      ]}

      {...other}
    >
      <div
        className="ListItem__container"
        css={{ display: "flex", alignItems: "center" }}
      >
        {contentBefore && (
          <div
            className="ListItem__content-before"
            css={{ marginRight: theme.spaces.md }}
          >
            {contentBefore}
          </div>
        )}

        <div
          className="ListItem__content"
          css={[
              {
                  flex: 1,
                  overflow: "hidden",
              },
              interactive && {
                  cursor: "pointer",
                  ":focus": {
                      boxShadow: `inset 0 0 3px ${theme.colors.text.selected}`
                  },
                  ":focus:not([data-focus-visible-added])": {
                      boxShadow: "none"
                  }
              },
              interactive &&
              hover && {
                  background: theme.colors.background.tint1
              },
              interactive &&
              active && {
                  background: theme.colors.background.tint2
              }
          ]}
          {...interactiveProps}
          {...safeBind(!noBind&&interactive ? bind : {}) }
        >
          <Text
            className="ListItem__primary"
            wrap={wrap}
            variant="body"
            css={{ display: "block", fontWeight: 500 }}
          >
            {primary}
          </Text>
          {secondary && (
            <Text
              className="ListItem__secondary"
              wrap={wrap}
              css={[
                {
                  display: "block",
                  fontSize: theme.fontSizes[0],
                },
                secondStyle
              ]}
              variant="body"
              muted
            >
              {secondary}
            </Text>
          )}
          {children}
        </div>
        {contentAfter && (
          <div
            className="ListItem__content-after"
            css={{ flex: "0 0 auto" }}
          >
            {contentAfter}
          </div>
        )}
      </div>
    </Component>
  );
};


interface ListSectionProps extends React.HTMLAttributes<HTMLDivElement> {
  /** A title of the section */
  title: string;
  children?: React.ReactNode;
  /** whether the title should stick to the top of the scrollable content */
  sticky?: boolean;
}

export const ListSection: React.FunctionComponent<ListSectionProps> = ({
  title,
  children,
  sticky = true,
  ...other
}) => {
  const theme = useTheme();
  const bg = theme.colors.background.layer;
  return (
    <div
      css={{
        ":first-child > *": {
          borderTop: "none"
        }
      }}
    >
      <MenuLabel
        css={{
          position: sticky ? "sticky" : "static",
          top: 0,
          backgroundColor: sticky ? bg : "transparent",
          padding: theme.spaces.sm,
          paddingLeft: theme.spaces.md,
          marginTop: theme.spaces.md,
          [theme.mediaQueries.lg]: {
            paddingLeft: theme.spaces.lg,
            paddingRight: theme.spaces.lg
          }
        }}
        {...other}
      >
        {title}
      </MenuLabel>
      {children}
    </div>
  );
};

ListSection.propTypes = {
  title: PropTypes.string.isRequired,
  sticky: PropTypes.bool,
  children: PropTypes.node
};


interface ListFlexRowProps extends React.HTMLAttributes<any> {
  onPress?: OnPressFunction;
  /**主体标签 默认=div
   * ElementType<any> 是任意标签或组件。 component={"li"} component={RouterLink} 组件儿子嵌套法的。
   * 很多w3c标签能用但样式有些变动，但是 "select" "svg" 不能用。
   *  */
  component?: React.ElementType<any>;

  /** 前面 在水平方向并排
   *  */
  contentBefore?: React.ReactNode;
  /** 后面 在水平方向并排
   * */
  contentAfter?: React.ReactNode;

  /** whether the list item is interactive (ie., can be clicked as a button) */
  interactive?: boolean;
  /** 更多内容。
   * primary secondary +children: 三个部分实际布局不做区分。
   * */
  children?: React.ReactNode;
  /** whether primary and secondary text should be wrapped */
  wrap?: boolean;
  /** The primary text content of the list item
   *  主要内容，样式不同
   * */
  primary?: string | React.ReactNode;
  /** the secondary text content
   *  附加内容，样式不同
   * */
  secondary?: string | React.ReactNode;
  noBind?:boolean;  //防止Can't perform a React state update on an unmounted component
  terminateOnScroll?: boolean;
  delay?: number;
  //对第二行secondary整行的控制
  secondStyle?: SerializedStyles;
  [key: string]: any; // back hack to permit things like to='/page'
}

/**代替ListItem,实现更为自由样式, 类比Table组件的每一行TableRow功能。
 <ListFlexRow css={{
        padding: "0.3rem 0.3rem",
        alignItems: "center",
        display: "flex",
        justifyContent: "space-between",
        "& em": {
        fontStyle: "normal",
            color: theme.colors.text.selected
        },
        "& > *": {
            flex: 1,
                overflow: "hidden"
        }
    }}
 > </ListFlexRow>
 若通过<ListFlexRow css={{padding: "0.3rem 0.3rem",}}的，在这里实际由...other接受了外部样式注入修改。
 * */
export const ListFlexRow: React.FunctionComponent<ListFlexRowProps> = ({
             primary,
             secondary,
             contentBefore,
             interactive = true,
             children,
             wrap = true,
             contentAfter,
             onPress = noOp,
             component: Component = "div",
             noBind=false,
             terminateOnScroll = false,
             delay=30,
             secondStyle,
             ...other
           }) => {
  const interactiveProps = interactive
      ? {
        role: "button",
        tabIndex: 0
      }
      : {};
  const isLink = other.to || other.href;
  const { bind, hover, active } = useTouchable({
    onPress,
    behavior: isLink ? "link" : "button"
  });
  const theme = useTheme();

  return (
      <Component
          className="ListFlexRow"
          css={[
            {
              display: 'flex',
              flexDirection: 'row',
              alignContent: 'center',
              justifyContent: 'space-between',
              alignItems: 'center',
              flexWrap: 'nowrap',
              textDecoration: "none",
              outline: "none",
              padding: "0.15rem 0.2rem",
              background: "transparent",
              WebkitTapHighlightColor: "transparent",
              transition: "background 0.07s ease",
              [theme.mediaQueries.md]: {
                padding: `0.15rem 0.4rem`,
              },
              [theme.mediaQueries.xl]: {
                padding: `${theme.spaces.xs} 1rem`,
              },
              ":last-child": {
                borderBottom: "none"
              }
            },
            interactive && {
              cursor: "pointer",
              ":focus": {
                boxShadow: `inset 0 0 3px ${theme.colors.text.selected}`
              },
              ":focus:not([data-focus-visible-added])": {
                boxShadow: "none"
              }
            },
            interactive &&
            hover && {
              background: theme.colors.background.tint1
            },
            interactive &&
            active && {
              background: theme.colors.background.tint2
            }
          ]}
          {...interactiveProps}
          {...safeBind(!noBind&&interactive ? bind : {}, other)}
      >
        {contentBefore && (
            <div
                className="ListFlexRow-before"
                css={{ marginRight: theme.spaces.md }}
            >
              {contentBefore}
            </div>
        )}

        <div className="ListFlexRow_content"
             css={{
               display: 'flex',
               flexDirection: 'row',
               alignContent: 'center',
               justifyContent: 'space-between',
               alignItems: 'center',
               flexWrap: 'wrap',
               flex: 1,
             }}
        >
          {primary && (
              <Text
                  className="ListFlexRow_primary"
                  wrap={wrap}
                  variant="body"
                  css={{ fontWeight: 500 }}
              >
                {primary}
              </Text>
          )}
          {secondary && (
              <Text
                  className="ListFlexRow_secondary"
                  wrap={wrap}
                  css={[
                    {
                      fontSize: theme.fontSizes[0],
                    },
                    secondStyle
                  ]}
                  variant="body"
                  muted
              >
                {secondary}
              </Text>
          )}

          {children}
        </div>

        {contentAfter && (
            <div
                className="ListFlexRow-after"
                css={{ flex: "0 0 auto" }}
            >
              {contentAfter}
            </div>
        )}
      </Component>
  );
};

